PythonでCron式から実行日付を取得する
はじめに
データアナリティクス事業本部のkobayashiです。
pythonでCron形式のスケジュール式から実際の実行時刻を計算する必要がありなにか良いパッケージはないかと探していたところピッタリなパッケージがあったので使ってみたいと思います。またAmazon EventBridgeのAWSサービスで使われるCron形式は一般的なCron形式を扱うcroniterでは計算できないのでこちらはpyawscronのパッケージを使ってみたいと思います。
Cron形式から実行時間を計算してみる
環境
- Python: 3.11.4
- croniter: 2.0.5
- pyawscron: 1.0.6
それではcroniterとpyawscronでCron形式から実行時間を計算してみたいと思います。
croniterを使って一般的なCron形式を扱う
はじめに一般的なCron形式を扱うcroniterで実行時間を計算してみます。
インストールはいつも通りのpipを使います。
pip install croniter
では早速croniterを使ってみます。 実行するのは下記のコードになります。
from croniter import croniter from datetime import datetime, timezone cron_expression_1 = "0 10 * * *" # 毎日午前 10:00に実行 cron_expression_2 = "15 12 * * *" # 毎日午後 12:15に実行 cron_expression_3 = "0 18 * * MON-FRI" # 毎週月曜日から金曜日まで午後 6:00に実行 cron_expression_4 = "0 8 1 * *" # 毎月 1 日の午前 8:00に実行 cron_expression_5 = "0/15 * * * *" # 15 分ごとに実行 # 基準日を設定 base_dt = datetime(2024, 4, 1, 10, 1, tzinfo=timezone.utc) # 次の実行時間を計算 print("毎日午前 10:00に実行") iter = croniter(cron_expression_1, base_dt) for _i in range(3): dt = iter.get_next(datetime) print(dt) print("毎日午後 12:15に実行") iter = croniter(cron_expression_2, base_dt) for _i in range(3): dt = iter.get_next(datetime) print(dt) print("毎週月曜日から金曜日まで午後 6:00に実行") iter = croniter(cron_expression_3, base_dt) for _i in range(6): dt = iter.get_next(datetime) print(dt) print("毎月 1 日の午前 8:00に実行") iter = croniter(cron_expression_4, base_dt) for _i in range(3): dt = iter.get_next(datetime) print(dt) print("15 分ごとに実行") iter = croniter(cron_expression_5, base_dt) for _i in range(3): dt = iter.get_next(datetime) print(dt)
croniterを使う際に必要なパラメータはCron式と基準時間の2つです。
from croniter import croniter
でcroniterをインポートした上でcroniter()
でイテレータを生成してから実行時間を計算します。上記のスクリプトを実行すると以下のような結果が得られ想定通りCron形式から実行時間を計算できました。
毎日午前 10:00に実行 2024-04-02 10:00:00+00:00 2024-04-03 10:00:00+00:00 2024-04-04 10:00:00+00:00 毎日午後 12:15に実行 2024-04-01 12:15:00+00:00 2024-04-02 12:15:00+00:00 2024-04-03 12:15:00+00:00 毎週月曜日から金曜日まで午後 6:00に実行 2024-04-01 18:00:00+00:00 2024-04-02 18:00:00+00:00 2024-04-03 18:00:00+00:00 2024-04-04 18:00:00+00:00 2024-04-05 18:00:00+00:00 2024-04-08 18:00:00+00:00 毎月 1 日の午前 8:00に実行 2024-05-01 08:00:00+00:00 2024-06-01 08:00:00+00:00 2024-07-01 08:00:00+00:00 15 分ごとに実行 2024-04-01 10:15:00+00:00 2024-04-01 10:30:00+00:00 2024-04-01 10:45:00+00:00
croniterは次の実行時間だけではなく前の実行時間も計算できます。
from croniter import croniter from datetime import datetime, timezone cron_expression_1 = "0 10 * * *" # 毎日午前 10:00に実行 # 基準日を設定 base_dt = datetime(2024, 4, 1, 10, 1, tzinfo=timezone.utc) # 前の実行時間を計算 print("毎日午前 10:00に実行") iter = croniter(cron_expression_1, base_dt) for _i in range(3): dt = iter.get_prev(datetime) print(dt)
次の実行時間はget_next
で取得していましたが前の実行時間はget_prev
で取得できます。
毎日午前 10:00に実行 2024-04-01 10:00:00+00:00 2024-03-31 10:00:00+00:00 2024-03-30 10:00:00+00:00
croniterには実行時間の計算だけでなくcroniter.match
を使うことでCron式の検算を行うこともできます。
croniter.match("0 10 * * *", datetime(2024, 4, 1, 10, 1, tzinfo=timezone.utc)) > False croniter.match("0 10 * * *", datetime(2024, 4, 1, 10, 0, tzinfo=timezone.utc)) > True
pyawscronを使ってAWSのCron形式を扱う
次にAWSのCron形式を扱うpyawscronで実行時間を計算してみます。
インストールはこちらもいつも通りのpipを使います。
pip install pyawscron
ではpyawscronを使ってみます。 実行するのは下記のコードになります。
from pyawscron import AWSCron from datetime import datetime, timezone cron_expression_1 = "0 10 * * ? *" # 毎日午前 10:00に実行 cron_expression_2 = "15 12 * * ? *" # 毎日午後 12:15に実行 cron_expression_3 = "0 18 ? * MON-FRI *" # 毎週月曜日から金曜日まで午後 6:00に実行 cron_expression_4 = "0 8 1 * ? *" # 毎月 1 日の午前 8:00に実行 cron_expression_5 = "0/15 * * * ? *" # 15 分ごとに実行 # 基準日を設定 base_dt = datetime(2024, 4, 1, 10, 1, tzinfo=timezone.utc) # 次の実行時間を計算 print("毎日午前 10:00に実行") aws_cron = AWSCron(cron_expression_1) dt = base_dt for _i in range(3): dt = aws_cron.occurrence(dt).next() print(dt) print("毎日午後 12:15に実行") aws_cron = AWSCron(cron_expression_2) dt = base_dt for _i in range(3): dt = aws_cron.occurrence(dt).next() print(dt) print("毎週月曜日から金曜日まで午後 6:00に実行") aws_cron = AWSCron(cron_expression_3) dt = base_dt for _i in range(6): dt = aws_cron.occurrence(dt).next() print(dt) print("毎月 1 日の午前 8:00に実行") aws_cron = AWSCron(cron_expression_4) dt = base_dt for _i in range(3): dt = aws_cron.occurrence(dt).next() print(dt) print("15 分ごとに実行") aws_cron = AWSCron(cron_expression_5) dt = base_dt for _i in range(3): dt = aws_cron.occurrence(dt).next() print(dt)
pyawscronを使う際に必要なパラメータもcroniterと同様にCron式と基準時間の2つです。
from pyawscron import AWSCron
でAWSCronをインポートしてからAWSCron()
でインスタンスを作成してからnext()
メソッドで実行時間を取得します。
上記のスクリプトを実行するとcroniterと同じ結果が得られ想定通りCron形式から実行時間を計算できました。
毎日午前 10:00に実行 2024-04-02 10:00:00+00:00 2024-04-03 10:00:00+00:00 2024-04-04 10:00:00+00:00 毎日午後 12:15に実行 2024-04-01 12:15:00+00:00 2024-04-02 12:15:00+00:00 2024-04-03 12:15:00+00:00 毎週月曜日から金曜日まで午後 6:00に実行 2024-04-01 18:00:00+00:00 2024-04-02 18:00:00+00:00 2024-04-03 18:00:00+00:00 2024-04-04 18:00:00+00:00 2024-04-05 18:00:00+00:00 2024-04-08 18:00:00+00:00 毎月 1 日の午前 8:00に実行 2024-05-01 08:00:00+00:00 2024-06-01 08:00:00+00:00 2024-07-01 08:00:00+00:00 15 分ごとに実行 2024-04-01 10:15:00+00:00 2024-04-01 10:30:00+00:00 2024-04-01 10:45:00+00:00
pyawscronはcroniterと同じようには次の実行時間だけではなく前の実行時間も計算できます。
from pyawscron import AWSCron from datetime import datetime, timezone cron_expression_1 = "0 10 * * ? *" # 毎日午前 10:00に実行 # 基準日を設定 base_dt = datetime(2024, 4, 1, 10, 1, tzinfo=timezone.utc) # 前の実行時間を計算 print("毎日午前 10:00に実行") aws_cron = AWSCron(cron_expression_1) dt = base_dt for _i in range(3): dt = aws_cron.occurrence(dt).prev() print(dt)
pyawscronでは次の実行時間はnext()
で取得していましたが前の実行時間はprev()
で取得できます。
毎日午前 10:00に実行 2024-04-01 10:00:00+00:00 2024-03-31 10:00:00+00:00 2024-03-30 10:00:00+00:00
まとめ
pythonでCron形式のスケジュール式から実際の実行時刻を計算するcroniterのパッケージ使って実行時間を取得できることを試してみました。またAmazon EventBridgeのAWSサービスで使われるCron形式ではpyawscronのパッケージを使って実行時間を取得してみました。使う場面はあまり多くないと思いますがどちらも簡単に実行時間が取得できました。
最後まで読んで頂いてありがとうございました。